package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.model.dto.TeachplanDTO;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.enums.content.CourseGradeEnum;
import com.xuecheng.common.enums.content.CourseModeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.JsonUtil;
import com.xuecheng.content.common.constant.ContentErrorCode;
import com.xuecheng.content.common.utils.QiniuUtils;
import com.xuecheng.content.entity.CourseBase;
import com.xuecheng.content.entity.CourseMarket;
import com.xuecheng.content.entity.CoursePub;
import com.xuecheng.content.mapper.CoursePubMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.CoursePubService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.HashMap;

/**
 * <p>
 * 课程发布 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CoursePubServiceImpl extends ServiceImpl<CoursePubMapper, CoursePub> implements CoursePubService {
    @Autowired
    private CourseBaseService courseBaseService;

    @Autowired
    private Configuration configuration;

    /*
     * #生成静态化页面发布位置
     * course.publish.position = pages/
     * #七牛云的存储消息
     * file.qiniu.accessKey = 自己的七牛云accessKey
     * file.qiniu.secretKey = 自己的七牛云secretKey
     * file.qiniu.bucket = 自己的七牛云静态页面空间名称
     */
    @Value("${course.publish.position}")
    private String position;
    @Value("${file.qiniu.accessKey}")
    private String accessKey;
    @Value("${file.qiniu.secretKey}")
    private String secretKey;
    @Value("${file.qiniu.bucket}")
    private String bucket;


    /**
     * 发布课程详情页
     *
     * @param courseBaseId 课程id
     *                     ===业务分析===
     *                     1.判断课程审核状态和课程发布数据
     *                     2.生成课程详情页面(Freemarker)'
     *                     3.将生成的页面文件上传到七牛云指定位置(使用工具类)
     */
    @Override
    public void publishPage(Long courseBaseId) {
        //1.判断课程审核状态
        CourseBase courseBase = this.courseBaseService.getById(courseBaseId);
        //判断课程审核状态
        //课程页面生成和上传到七牛上,必须保证课程审核状态为:课程已发布
        if (!ObjectUtils.nullSafeEquals(courseBase.getAuditStatus(), CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode())) {
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
        //判断课程发布信息
        LambdaQueryWrapper<CoursePub> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CoursePub::getCourseId, courseBaseId);
        CoursePub coursePub = this.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(coursePub)) {
            ExceptionCast.cast(ContentErrorCode.E_120203);
        }
        //2.生成课程详情页面(Freemarker)
        //获取数据模型
        try {
            HashMap<String, Object> dataMap = this.generateDataMap(coursePub);
            //页面模板
            Template template = configuration.getTemplate("learing_article.ftl");
            String stringHTML = FreeMarkerTemplateUtils.processTemplateIntoString(template, dataMap);
            //3.将生成的页面文件上传到七牛云指定位置
            //课程详情页名称:pages/课程发布信息id+.html
            String fileKey = position + coursePub.getId() + ".html";
            QiniuUtils.upload2Qiniu(accessKey, secretKey, bucket, stringHTML, fileKey);


        } catch (Exception e) {
            ExceptionCast.castWithException(ContentErrorCode.E_120204, e);
        }

        //4.修改课程发布数据(is_pub=0)
        LambdaUpdateWrapper<CoursePub> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CoursePub::getIsPub, CoursePub.IS_PUB);
        updateWrapper.set(CoursePub::getChangeDate, LocalDateTime.now());
        updateWrapper.eq(CoursePub::getId, coursePub.getId());
        boolean result = this.update(updateWrapper);
        if (!result) {
            ExceptionCast.cast(ContentErrorCode.E_120205);
        }
    }

    private HashMap<String, Object> generateDataMap(CoursePub coursePub) {
        //9.封装数据模型数据dataMap并返回
        HashMap<String, Object> dataMap = new HashMap<>();
        //1.课程发布
        dataMap.put("coursePub", coursePub);
        //2.课程营销
        String jsonMarket = coursePub.getMarket();
        CourseMarket courseMarket = JsonUtil.jsonToObject(jsonMarket, CourseMarket.class);
        dataMap.put("courseMarket", courseMarket);
        //3.课程计划
        String jsonTeachplan = coursePub.getTeachplan();
        TeachplanDTO teachplanNode = JsonUtil.jsonToObject(jsonTeachplan, TeachplanDTO.class);
        dataMap.put("teachplanNode", teachplanNode);
        dataMap.put("courseGradeEnums", CourseGradeEnum.values());

        //7.获取课程的教学模式
        dataMap.put("courseTeachModeEnums", CourseModeEnum.values());

        return dataMap;
    }
}
